﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Windows.Forms;

namespace PathFinder
{
    [Serializable()]
    public class Project
    {
        #region class definitions
        String projectPath = "";
        public String ProjectPath { get { return projectPath; } }
        Graph graph;
        public Graph Graph { get { return graph; } set { graph = value; } }
        Image image = null;
        public Image Image { get { return image; } }
        Size size;
        public Size Size { get { return size; } set { size = value; } }
        bool hasImage;
        public bool HasImage { get { return hasImage; } set { hasImage = value; } }
        public Project() { }
        
        public Project(Graph Graph, Image Image)
        {
            graph = Graph;
            image = Image;
            hasImage = true;
            size = image.Size;
        }
        
        public Project(Graph Graph, Size Size)
        {
            graph = Graph;
            size = Size;
            image = null;
        }

        #endregion

        private String ParseProjectPath(bool isReal)
        {
            if (isReal)
                return projectPath.Substring(0, projectPath.Length - 3) + "jpg";
            return projectPath.Substring(0, projectPath.Length - 4) + "WorkCopy.jpg";
        }

        public static Image LoadImageSafelyFromFile(String FilePath)
        {
            Image img = null;
            try
            {
                using (Image imgTmp = Image.FromFile(FilePath))
                {
                    img = new Bitmap(imgTmp.Width, imgTmp.Height, imgTmp.PixelFormat);
                    Graphics gdi = Graphics.FromImage(img);
                    gdi.DrawImageUnscaled(imgTmp, 0, 0);
                    gdi.Dispose();
                    imgTmp.Dispose();
                }
                if(img != null)
                    if (img.Width > 4000 || img.Height > 4000)
                    {
                        MessageBox.Show("Too big image, maximal size is 4000x4000!", "Warning");
                        return null;
                    }
                return img;
            }
            catch (Exception exc)
            {
                return null;
            }
        }

        public static Project Load(String FilePath)
        {
            try
            {
                String xmlString = File.ReadAllText(FilePath);
                byte[] bytes = Encoding.UTF8.GetBytes(xmlString);
                MemoryStream mem = new MemoryStream(bytes);
                XmlSerializer ser = new XmlSerializer(typeof(Project));
                Project p = (Project)ser.Deserialize(mem);
                if (p.Size.Width > 4000 || p.Size.Height > 4000 || p.Size.Width < 400 || p.Size.Height < 400)
                    throw new FormatException();
                p.graph.RebuildPointers(p.Size);
                p.projectPath = FilePath;
                if (p.hasImage)
                {
                    p.image = Project.LoadImageSafelyFromFile(p.ParseProjectPath(true));
                    if (p.image == null)
                    {
                        MessageBox.Show("Background picture not found, continuing without picture.", "Warning");
                        p.hasImage = false;
                    }
                }
                return p;
            }
            catch (Exception exc)
            {
                MessageBox.Show("Incorrect or corrupted project file.", "Warning");
                return null;
            }
        }

        public bool Save()
        {
            try
            {
                File.Delete(projectPath);
                XmlSerializer x = new XmlSerializer(this.GetType());
                FileStream o = new FileStream(projectPath, FileMode.OpenOrCreate, FileAccess.Write);
                x.Serialize(o, this);
                o.Close();
                if (image != null)
                {
                        image.Save(ParseProjectPath(true));
                }
                return true;
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
                return false;
            }
        }

        public bool SaveAs(String FilePath)
        {
            try
            {
                File.Delete(FilePath);
                XmlSerializer x = new XmlSerializer(this.GetType());
                FileStream o = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.Write);
                x.Serialize(o, this);
                o.Close();
                projectPath = FilePath;
                if (image != null)
                {
                    image.Save(ParseProjectPath(true));
                }
                return true;
            }
            catch (Exception exc)
            {
                MessageBox.Show("Unexpected error, project was not saved!", "Warning");
                return false;
            }
        }
       
    }
}
